package com.tencent.sr.iris.activity.service.task.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tencent.sr.iris.activity.common.constant.QuFaHttpConstant;
import com.tencent.sr.iris.activity.common.enums.IrisErrorCode;
import com.tencent.sr.iris.activity.common.util.AssertUtils;
import com.tencent.sr.iris.activity.common.util.QuFaHttpUtil;
import com.tencent.sr.iris.activity.dependency.qufa.GroupTaskDependency;
import com.tencent.sr.iris.activity.dependency.user.UserCoreDependency;
import com.tencent.sr.iris.activity.domain.event.dto.ActivityCheckResultDTO;
import com.tencent.sr.iris.activity.interfaces.enums.ActivityTypeEnum;
import com.tencent.sr.iris.activity.interfaces.enums.IsParticipatedEnum;
import com.tencent.sr.iris.activity.interfaces.request.acticity.AwardStaticRequest;
import com.tencent.sr.iris.activity.interfaces.request.acticity.TaskRecordRequest;
import com.tencent.sr.iris.activity.interfaces.request.task.TaskCommissionRequest;
import com.tencent.sr.iris.activity.interfaces.request.task.TaskIncomeRequest;
import com.tencent.sr.iris.activity.interfaces.request.task.TaskRewardListRequest;
import com.tencent.sr.iris.activity.interfaces.response.activity.AwardStaticResponse;
import com.tencent.sr.iris.activity.interfaces.response.group.task.TaskCommissionDetailResponse;
import com.tencent.sr.iris.activity.interfaces.response.group.task.TaskCommissionResponse;
import com.tencent.sr.iris.activity.interfaces.response.group.task.TaskIncomeResponse;
import com.tencent.sr.iris.activity.interfaces.response.group.task.TaskRewardListResponse;
import com.tencent.sr.iris.activity.service.activity.IrisUserTaskRecordService;
import com.tencent.sr.iris.activity.service.convert.AwardStaticConvert;
import com.tencent.sr.iris.activity.service.event.activity.IrisInviteGiftActivityExecutor;
import com.tencent.sr.iris.activity.service.event.activity.SpecialIrisInviteGiftActivityExecutor;
import com.tencent.sr.iris.activity.service.task.CommissionGroupTaskService;
import com.tencent.sr.iris.user.core.service.interfaces.response.user.UserUnionIdResponse;
import com.tencent.sr.rmall.common.exception.retail.TRetailBizException;
import com.tencent.sr.rmall.common.request.PaginationRequest;
import com.tencent.sr.rmall.common.response.PaginationResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Component
public class CommissionGroupTaskServiceImpl implements CommissionGroupTaskService {

    @Resource
    private QuFaHttpUtil quFaHttpUtil;

    @Resource
    private GroupTaskDependency groupTaskDependency;

    @Resource
    private IrisUserTaskRecordService userTaskRecordService;

    @Resource
    private AwardStaticConvert awardStaticConvert;

    @Resource
    private UserCoreDependency userCoreDependency;

    @Resource
    private SpecialIrisInviteGiftActivityExecutor specialIrisInviteGiftActivityExecutor;

    @Resource
    private IrisInviteGiftActivityExecutor irisInviteGiftActivityExecutor;

    @Override
    public TaskCommissionResponse taskReward(TaskCommissionRequest request) {
        String unionId = request.getUnionId();
        Long startTime = request.getStartTime();
        Long endTime = request.getEndTime();
        String uid = request.getUid();
        if (StrUtil.isBlank(uid)) {
            UserUnionIdResponse userInfo = userCoreDependency.getUserInfoByUnionId(unionId);
            AssertUtils.isNotNull(userInfo, IrisErrorCode.USER_NOT_EXIST);
            uid = userInfo.getUid();
        }

        TaskIncomeRequest taskIncomeRequest = new TaskIncomeRequest()
                .setUid(uid).setStartTime(Optional.ofNullable(startTime).map(String::valueOf).orElse(null))
                .setEndTime(Optional.ofNullable(endTime).map(String::valueOf).orElse(null));
        TaskIncomeResponse incomeResponse = taskRewardNew(taskIncomeRequest);

        int goingInviteActivity = getGoingInviteActivity(uid);

        TaskCommissionResponse response = new TaskCommissionResponse();
        //进行中的任务，已结束任务，这两个 数据目前是只有区发数据，需要加上邀请有礼，如果上级满足邀请有礼准入门槛，则进行中加1，如果满足特邀邀请有礼准入门槛则进行中再加1；已结束不动
        response.setGoingTaskPhaseCount(Optional.ofNullable(incomeResponse.getGoingTaskPhaseCount()).orElse(0) + goingInviteActivity);
        response.setEndedTaskPhaseCount(Optional.ofNullable(incomeResponse.getEndedTaskPhaseCount()).orElse(0));
        //预估奖励金额 和c任务奖励 - 预估总收益 保持一致，包含区发任务奖励 + 邀请有礼的预估奖励
        //实际奖励金额 和c任务奖励 - 已确认收益 保持一致，包含区发任务奖励 + 邀请有礼的实际奖励
        response.setEstimateReward(Optional.ofNullable(incomeResponse).map(i -> (long) i.getPredictIncome()).orElse(0l));
        response.setAwardAmount(Optional.ofNullable(incomeResponse).map(i -> (long) i.getTaskBonusSettlementBillAmount()).orElse(0l));
        log.info("区发获取任务奖励 request:{} response:{}", request, response);
        return response;
    }

    /**
     * 获取进行中的邀请有礼数量
     * @param uid
     * @return
     */
    private int getGoingInviteActivity(String uid) {
        int goingInviteActivity = 0;
        ActivityCheckResultDTO activityCheckResultDTO;
        try {
            activityCheckResultDTO = specialIrisInviteGiftActivityExecutor.doPidAccessConditionCheck(uid, null, null);
            if (activityCheckResultDTO == null || activityCheckResultDTO.isSatisfy()) {
                goingInviteActivity++;
            }
        } catch (Exception e) {
            log.error("特邀邀请有礼准入门槛校验失败，uid：{}", uid, e);
        }
        try {
            activityCheckResultDTO = irisInviteGiftActivityExecutor.doPidAccessConditionCheck(uid, null, null);
            if (activityCheckResultDTO == null || activityCheckResultDTO.isSatisfy()) {
                goingInviteActivity++;
            }
        } catch (Exception e) {
            log.error("邀请有礼准入门槛校验失败，uid：{}", uid, e);
        }

        return goingInviteActivity;
    }

    @Override
    public TaskIncomeResponse taskRewardNew(TaskIncomeRequest request) {
        //加上邀请有礼的预估收益，重新计算待确认收益
        AwardStaticRequest staticRequest = awardStaticConvert.buildFromTaskIncomeRequest(request);
        staticRequest.setActivityTypes(Arrays.asList(ActivityTypeEnum.INVITE_GIFT));

        AwardStaticResponse staticResponse = userTaskRecordService.awardStatic(staticRequest);
        log.info("任务收益邀请有礼统计，uid：{}，req：{}，response：{}", request.getUid(), JSON.toJSONString(staticRequest), JSON.toJSONString(staticResponse));

        Long estimateCommission = staticResponse.getEstimateCommission();

        TaskIncomeResponse taskIncomeResponse = groupTaskDependency.myIncome(request);
        log.info("任务收益区发统计，uid：{}，req：{}，response：{}", request.getUid(), JSON.toJSONString(request), JSON.toJSONString(taskIncomeResponse));
        taskIncomeResponse.setPredictIncome(Math.toIntExact(estimateCommission + taskIncomeResponse.getPredictIncome()));
        int waitTaskBonusSettlementBillAmount = taskIncomeResponse.getPredictIncome() - taskIncomeResponse.getTaskBonusSettlementBillAmount();
        if (waitTaskBonusSettlementBillAmount < 0) {
            log.warn("待确认收益小于0，邀请有礼收益数据：{}，营销收益数据：{}",
                    JSONObject.toJSONString(staticResponse), JSONObject.toJSONString(taskIncomeResponse));
            taskIncomeResponse.setWaitTaskBonusSettlementBillAmount(0);
        } else {
            taskIncomeResponse.setWaitTaskBonusSettlementBillAmount(waitTaskBonusSettlementBillAmount);
        }

        TaskRecordRequest taskRecordRequest = new TaskRecordRequest()
                .setUid(request.getUid())
                .setStartTime(staticRequest.getStartTime())
                .setEndTime(staticRequest.getEndTime())
                .setActivityTypes(Arrays.asList(ActivityTypeEnum.INVITE_GIFT))
                .setParticipated(IsParticipatedEnum.YES)
                .setQueryCurrentTaskStartTime(true);

        List<TaskCommissionDetailResponse> waitTaskPhaseData = userTaskRecordService
                .getWaitTaskPhaseData(taskRecordRequest);

        //合并待确认详细数据
        List<TaskCommissionDetailResponse> detailResponses = Optional
                .ofNullable(taskIncomeResponse.getWaitTaskPhaseData()).orElseGet(Collections::emptyList);
        detailResponses.addAll(waitTaskPhaseData);
        taskIncomeResponse.setWaitTaskPhaseData(detailResponses);
        return taskIncomeResponse;
    }

    @Override
    public PaginationResponse<TaskRewardListResponse> pageRewardList(PaginationRequest<TaskRewardListRequest> request) {
        PaginationResponse<TaskRewardListResponse> response = quFaHttpUtil.postPageList(
                QuFaHttpConstant.TASK_COMMISSION_LIST, formatTaskPageRequest(request), TaskRewardListResponse.class);
        log.info("区发分页获取任务奖励明细, unionId:{} response:{}", request.getQueryCriteria().getUnionId(), response);
        return response;
    }

    private JSONObject formatTaskPageRequest(PaginationRequest<TaskRewardListRequest> request) {
        JSONObject jsonObject = new JSONObject();
        TaskRewardListRequest queryCriteria = request.getQueryCriteria();
        if (Objects.isNull(queryCriteria)) {
            throw new TRetailBizException(IrisErrorCode.PARAM_ERROR);
        }
        if (queryCriteria.getStartTime() != null) {
            jsonObject.put("task_phase_join_start_time",
                    DateUtil.format(DateUtil.date(queryCriteria.getStartTime()), "yyyy-MM-dd HH:mm:ss"));
        }
        if (queryCriteria.getEndTime() != null) {
            jsonObject.put("task_phase_join_end_time",
                    DateUtil.format(DateUtil.date(queryCriteria.getEndTime()), "yyyy-MM-dd HH:mm:ss"));

        }
        jsonObject.put("wechat_user_union_id", queryCriteria.getUnionId());
        jsonObject.put("page", request.getPageNum());
        jsonObject.put("pre_page", request.getPageSize());
        return jsonObject;
    }
}
